﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG;
using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
using Microsoft.Rest;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RapidSalesAdminPortalAPI.DataAccess;
using RapidSalesAdminPortalAPI.Models;
using RapidSalesAdminPortalAPI.Services;
using ServiceReference1;
using ServiceReference2;
using ServiceReference3;
using ServiceReference4;
using System.Drawing.Imaging;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using WebAPI.Common;
using WebAPI.Controllers;

namespace RapidSalesAdminPortalAPI.Controllers
{
    public class CommonController : ParentController
    {
        private readonly RS_AdmPortalContext _context;
        private readonly IConfiguration Configuration;
        private ISoapService _soapService;
        private IWsAPIAccountSoap _apiAccountService;
        private IWsAPIOrderSoap _apiOrderService;
        private IWsAPIProductSoap _apiProdcutService;
        private IWsAPIPerformanceSoap _apiPerformanceService;
        private readonly ILogger<CommonController> _logger;

        public CommonController(RS_AdmPortalContext context, IConfiguration configuration, ISoapService soapService,
            IWsAPIAccountSoap apiAccountService, IWsAPIOrderSoap apiOrderService, IWsAPIProductSoap apiProdcutService, IWsAPIPerformanceSoap apiPerformanceService,
            ILogger<CommonController> logger)
        {
            _context = context;
            Configuration = configuration;
            _soapService = soapService;
            _apiAccountService = apiAccountService;
            _apiOrderService = apiOrderService;
            _apiProdcutService = apiProdcutService;
            _apiPerformanceService = apiPerformanceService;
            _logger = logger;
        }


        [NonAction]
        public async Task<string> GetToken()
        {
            try
            {
                var requestUrl = Configuration["RequestUrl"];
                var aUsername = Configuration["AUsername"];
                var aPsw = Configuration["APsw"];

                var dic = new Dictionary<string, object>();
                dic.Add("AUsername", aUsername);
                dic.Add("APsw", aPsw);
                string meothName = "B2BAccountLogIn";   //服务的方法名
                requestUrl = requestUrl + "IWsAPIAccount.asmx?op=" + meothName;
                var httpClientHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true
                };

                StringBuilder contentString = new StringBuilder();

                foreach (var item in dic)
                {
                    contentString.Append($"<{item.Key}>{item.Value}</{item.Key}>");
                }
                string contentValue = contentString.ToString();
                string content = $@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                   <soap:Body>
                     <{meothName} xmlns=""http://tempuri.org/"">
                         {contentValue}
                     </{meothName}>
                 </soap:Body>
              </soap:Envelope>";
                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "text/xml");

                HttpClient client = new HttpClient(httpClientHandler);

                var response = await client.PostAsync(requestUrl, httpContent);
                //var responseXml = await response.Content.ReadAsStringAsync();

                //XmlSerializer serializer = new XmlSerializer(typeof(B2BAccountLogInResponse));
                //using (StringReader reader = new StringReader(responseXml))
                //{
                //    B2BAccountLogInResponse data = (B2BAccountLogInResponse)serializer.Deserialize(reader);
                //}
                JObject obj = response.GetHeadersAsJson();// ["HeaderSrtore"]["Token"].ToString();
                if (obj != null)
                {
                    return obj?["Token"].ToString();
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }

        [HttpPost("FindB2BAccountProduct")]
        public async Task<ActionResult<ResultMsg>> FindB2BAccountProduct()
        {
            var resultMsg = new ResultMsg();
            try
            {
                var loginResp = await Login();
                var client = new WsAPIProductSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:ProductApiUrl"]));

                using (var operationContextScope = new OperationContextScope(client.InnerChannel))
                {
                    // 添加HTTP请求头  
                    var httpRequestProperty = new HttpRequestMessageProperty();
                    httpRequestProperty.Headers["token"] = loginResp.Toekn;

                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                    // 调用WebService方法  
                    var result = await client.FindB2BAccountProductAsync(loginResp?.B2BAccountLogin?.ACCOUNT.BASICINFO.ACCOUNTAK);

                    var insertProductList = new List<FrIpProduct>();
                    var insertEventList = new List<FrIpEvent>();
                    var insertProductEventList = new List<FrIpProductEvent>();
                    var insertEventTimeSlots = new List<FrIpEventTimeSlot>();
                    var delEventTimeSlots = new List<FrIpEventTimeSlot>();
                    var updateProductList = new List<FrIpProduct>();
                    var updateEventList = new List<FrIpEvent>();

                    //var oldProdcut = new List<FrIpProduct>();

                    if (result.Body != null && result.Body.@return != null && result.Body.@return.ERROR != null && result.Body.@return.ERROR.CODE == "200")
                    {
                        if (result.Body.@return.PRODUCTLIST != null && result.Body.@return.PRODUCTLIST.Count > 0)
                        {
                            var productCodeList = result.Body.@return.PRODUCTLIST.Select(x => x.CODE).ToList();
                            var existList = _context.FrIpProducts.AsQueryable().Select(x => x.ProductCode).ToList();
                            var insertCode = productCodeList.Except(existList).ToList();
                            var updateCode = productCodeList.Intersect(existList).ToList();
                            var updateList = _context.FrIpProducts.AsQueryable().Where(x => updateCode.Contains(x.ProductCode)).ToList();
                            //insert Product
                            foreach (var product in result.Body.@return.PRODUCTLIST.Where(x => insertCode.Contains(x.CODE)))//
                            {
                                Guid productId = Guid.NewGuid();
                                DateTime NowTime = DateTime.Now;
                                var engbModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "en-GB");
                                var zhTWModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "zh-TW");
                                var zhCnModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "zh-CN");
                                var insertProduct = new FrIpProduct()
                                {
                                    Id = productId,
                                    MatrixCellAk = product.AK,
                                    ProductCode = product.CODE,
                                    ProductNameEn = engbModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE,
                                    ProductNameTc = zhTWModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE,
                                    ProductNameSc = zhCnModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE,
                                    TicketDescriptionEn = engbModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE,
                                    TicketDescriptionTc = zhTWModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE,
                                    TicketDescriptionSc = zhCnModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE,
                                    UnitPrice = Convert.ToDecimal(product.PRICE.GROSS),
                                    Currency = product.PRICE.CURRENCY,
                                    IsRequired = product.WARNING.PERFORMANCE.REQUIRED,
                                    MaxPurchaseQty = product.WARNING.SALERESTRICTION.MAX == null ? 100000 : product.WARNING.SALERESTRICTION.MAX.GetValueOrDefault(),
                                    IsMaxPurchaseQty = product.WARNING.SALERESTRICTION.REQUIRED,
                                    CreateUser = CurrentUserId,
                                    UpdateUser = CurrentUserId,
                                    CreateDate = NowTime,
                                    UpdateDate = NowTime
                                };
                                insertProductList.Add(insertProduct);

                                if (product.EVENTLIST != null && product.EVENTLIST.Count > 0)
                                {
                                    foreach (var eventInfo in product.EVENTLIST)
                                    {
                                        Guid eventId = Guid.NewGuid();
                                        var productEventId = Guid.NewGuid();
                                        var productEvent = new FrIpProductEvent()
                                        {
                                            Id = productEventId,
                                            ProductId = productId,
                                            EventId = eventId
                                        };
                                        var clientPerformance = new WsAPIPerformanceSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:PerformanceApiUrl"]));
                                        using (var operationContextScopePer = new OperationContextScope(clientPerformance.InnerChannel))
                                        {
                                            // 添加HTTP请求头  
                                            var httpRequestPropertyPer = new HttpRequestMessageProperty();
                                            httpRequestProperty.Headers["token"] = loginResp?.Toekn;

                                            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                                            var PAGEREQ = new PAGEREQ()
                                            {
                                                PAGEINDEX = "1",
                                                PAGESIZE = "500",


                                                SORTFIELD = "DATETIME",
                                                SORTDIRECTION = "ASC",
                                            };
                                            var BASEDATEFILTER = new BASEDATEFILTER()
                                            {
                                                FROM = DateTime.Now.ToString("yyyy-MM-dd"),
                                                TO = DateTime.Now.ToString("yyyy-MM-dd"),
                                            };

                                            var performance = await clientPerformance.SearchPerformanceAsync(eventInfo.AK, "true", "", "", "", PAGEREQ, BASEDATEFILTER, null);
                                            if (performance != null && performance.@return != null && performance.@return.ERROR != null && performance.@return.ERROR.CODE == "200")
                                            {
                                                if (performance.@return.PERFORMANCELIST != null && performance.@return.PERFORMANCELIST.Length > 0)
                                                {
                                                    foreach (var item in performance.@return.PERFORMANCELIST)
                                                    {
                                                        Guid eventTimeSlotsId = Guid.NewGuid();
                                                        var eventTimeSlots = new FrIpEventTimeSlot()
                                                        {
                                                            Id = eventTimeSlotsId,
                                                            EventId = eventId,
                                                            StartDateTime = Convert.ToDateTime(item.DATETIME),
                                                            EndDateTime = Convert.ToDateTime(item.ENDDATETIME),
                                                            OpeningTime = item.OPENINGTIME,
                                                            ClosingTime = item.CLOSINGTIME,
                                                            IsFullDay = Convert.ToDateTime(item.DATETIME).Subtract(Convert.ToDateTime(item.DATETIME)).Hours >= 23 ? true : false,
                                                        };
                                                        insertEventTimeSlots.Add(eventTimeSlots);
                                                    }
                                                }
                                            }

                                            var insertEvent = new FrIpEvent()
                                            {
                                                Id = eventId,
                                                EventAk = eventInfo.AK,
                                                EventCode = eventInfo.CODE,
                                                CreateDate = NowTime,
                                                CreateUser = CurrentUserId,
                                                UpdateDate = NowTime,
                                                UpdateUser = CurrentUserId,
                                                Enable = true
                                            };
                                            insertEventList.Add(insertEvent);
                                            insertProductEventList.Add(productEvent);
                                        }
                                    }
                                }

                            }

                            //update Product
                            foreach (var updateProduct in updateList)//
                            {
                                var existEventCodeList = _context.FrIpProductEvents.Include(x => x.Event).Include(x => x.Product)
                                    .Where(x => x.Product.ProductCode == updateProduct.ProductCode).Select(x => x.Event.EventCode).ToList();
                                var product = result.Body.@return.PRODUCTLIST.FirstOrDefault(x => x.CODE == updateProduct.ProductCode);
                                DateTime NowTime = DateTime.Now;
                                var engbModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "en-GB");
                                var zhTWModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "zh-TW");
                                var zhCnModel = product.I18NLIST?.FirstOrDefault(x => x.CODE == "zh-CN");

                                updateProduct.MatrixCellAk = product.AK;
                                updateProduct.ProductCode = product.CODE;
                                updateProduct.ProductNameEn = engbModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE;
                                updateProduct.ProductNameTc = zhTWModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE;
                                updateProduct.ProductNameSc = zhCnModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 536)?.VALUE;
                                updateProduct.TicketDescriptionEn = engbModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE;
                                updateProduct.TicketDescriptionTc = zhTWModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE;
                                updateProduct.TicketDescriptionSc = zhCnModel?.FIELDLIST.FirstOrDefault(x => x.OBJTYPE == 537)?.VALUE;
                                updateProduct.UnitPrice = Convert.ToDecimal(product.PRICE.GROSS);
                                updateProduct.Currency = product.PRICE.CURRENCY;
                                updateProduct.IsRequired = product.WARNING.PERFORMANCE.REQUIRED;
                                updateProduct.MaxPurchaseQty = product.WARNING.SALERESTRICTION.MAX == null ? 100000 : product.WARNING.SALERESTRICTION.MAX.GetValueOrDefault();
                                updateProduct.IsMaxPurchaseQty = product.WARNING.SALERESTRICTION.REQUIRED;
                                updateProduct.UpdateUser = CurrentUserId;
                                updateProduct.UpdateDate = NowTime;
                                updateProductList.Add(updateProduct);


                                if (product.EVENTLIST != null && product.EVENTLIST.Count > 0)
                                {
                                    var eventCodeList = product.EVENTLIST.Select(x => x.CODE).ToList();

                                    var insertEventCode = eventCodeList.Except(existEventCodeList).ToList();
                                    var updateEventCode = eventCodeList.Intersect(existEventCodeList).ToList();
                                    //insert event
                                    foreach (var eventInfo in product.EVENTLIST.Where(x => insertEventCode.Contains(x.CODE)))
                                    {
                                        Guid eventId = Guid.NewGuid();
                                        var productEventId = Guid.NewGuid();
                                        var productEvent = new FrIpProductEvent()
                                        {
                                            Id = productEventId,
                                            ProductId = updateProduct.Id,
                                            EventId = eventId
                                        };
                             
                                        var clientPerformance = new WsAPIPerformanceSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:PerformanceApiUrl"]));
                                        using (var operationContextScopePer = new OperationContextScope(clientPerformance.InnerChannel))
                                        {
                                            // 添加HTTP请求头  
                                            var httpRequestPropertyPer = new HttpRequestMessageProperty();
                                            httpRequestProperty.Headers["token"] = loginResp?.Toekn;

                                            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                                            var PAGEREQ = new PAGEREQ()
                                            {
                                                PAGEINDEX = "1",
                                                PAGESIZE = "500",
                                                SORTFIELD = "DATETIME",
                                                SORTDIRECTION = "ASC",
                                            };
                                            var BASEDATEFILTER = new BASEDATEFILTER()
                                            {
                                                FROM = DateTime.Now.ToString("yyyy-MM-dd"),
                                                TO = DateTime.Now.ToString("yyyy-MM-dd"),
                                            };

                                            var performance = await clientPerformance.SearchPerformanceAsync(eventInfo.AK, "true", "", "", "", PAGEREQ, BASEDATEFILTER, null);
                                            if (performance != null && performance.@return != null && performance.@return.ERROR != null && performance.@return.ERROR.CODE == "200")
                                            {
                                                if (performance.@return.PERFORMANCELIST != null && performance.@return.PERFORMANCELIST.Length > 0)
                                                {
                                                    foreach (var item in performance.@return.PERFORMANCELIST)
                                                    {
                                                        Guid eventTimeSlotsId = Guid.NewGuid();
                                                        var eventTimeSlots = new FrIpEventTimeSlot()
                                                        {
                                                            Id = eventTimeSlotsId,
                                                            EventId = eventId,
                                                            StartDateTime = Convert.ToDateTime(item.DATETIME),
                                                            EndDateTime = Convert.ToDateTime(item.ENDDATETIME),
                                                            OpeningTime = item.OPENINGTIME,
                                                            ClosingTime = item.CLOSINGTIME,
                                                            IsFullDay = Convert.ToDateTime(item.DATETIME).Subtract(Convert.ToDateTime(item.DATETIME)).Hours >= 23 ? true : false,
                                                        };
                                                        insertEventTimeSlots.Add(eventTimeSlots);
                                                    }
                                                }
                                            }

                                            var insertEvent = new FrIpEvent()
                                            {
                                                Id = eventId,
                                                EventAk = eventInfo.AK,
                                                EventCode = eventInfo.CODE,
                                                CreateDate = NowTime,
                                                CreateUser = CurrentUserId,
                                                UpdateDate = NowTime,
                                                UpdateUser = CurrentUserId,
                                                Enable = true
                                            };
                                            insertEventList.Add(insertEvent);
                                            insertProductEventList.Add(productEvent);
                                        }
                                    }

                                    var updateApiEventList = _context.FrIpEvents.AsQueryable().Where(x => updateEventCode.Contains(x.EventCode)).ToList();
                                    //update event
                                    foreach (var eventInfo in updateApiEventList)
                                    {
                                        var eventApiInfo = product.EVENTLIST.FirstOrDefault(x => x.CODE == eventInfo.EventCode);
                                        Guid? oldEventId = _context.FrIpEvents.AsQueryable().FirstOrDefault(x => x.EventAk == eventInfo.EventAk)?.Id;
                                        var slotsList = _context.FrIpEventTimeSlots.AsQueryable().Where(x => x.EventId == oldEventId).ToList();
                                        delEventTimeSlots.AddRange(slotsList);
                                        var clientPerformance = new WsAPIPerformanceSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:PerformanceApiUrl"]));
                                        using (var operationContextScopePer = new OperationContextScope(clientPerformance.InnerChannel))
                                        {
                                            // 添加HTTP请求头  
                                            var httpRequestPropertyPer = new HttpRequestMessageProperty();
                                            httpRequestProperty.Headers["token"] = loginResp?.Toekn;

                                            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                                            var PAGEREQ = new PAGEREQ()
                                            {
                                                PAGEINDEX = "1",
                                                PAGESIZE = "500",
                                                SORTFIELD = "DATETIME",
                                                SORTDIRECTION = "ASC",
                                            };
                                            var BASEDATEFILTER = new BASEDATEFILTER()
                                            {
                                                FROM = DateTime.Now.ToString("yyyy-MM-dd"),
                                                TO = DateTime.Now.ToString("yyyy-MM-dd"),
                                            };

                                            var performance = await clientPerformance.SearchPerformanceAsync(eventInfo.EventAk, "true", "", "", "", PAGEREQ, BASEDATEFILTER, null);
                                            if (performance != null && performance.@return != null && performance.@return.ERROR != null && performance.@return.ERROR.CODE == "200")
                                            {
                                                if (performance.@return.PERFORMANCELIST != null && performance.@return.PERFORMANCELIST.Length > 0)
                                                {
                                                    foreach (var item in performance.@return.PERFORMANCELIST)
                                                    {
                                                        Guid eventTimeSlotsId = Guid.NewGuid();
                                                        var eventTimeSlots = new FrIpEventTimeSlot()
                                                        {
                                                            Id = eventTimeSlotsId,
                                                            EventId = eventInfo.Id,
                                                            StartDateTime = Convert.ToDateTime(item.DATETIME),
                                                            EndDateTime = Convert.ToDateTime(item.ENDDATETIME),
                                                            OpeningTime = item.OPENINGTIME,
                                                            ClosingTime = item.CLOSINGTIME,
                                                            IsFullDay = Convert.ToDateTime(item.DATETIME).Subtract(Convert.ToDateTime(item.DATETIME)).Hours >= 23 ? true : false,
                                                        };
                                                        insertEventTimeSlots.Add(eventTimeSlots);
                                                    }
                                                }

                                            }
                                            eventInfo.EventCode = eventApiInfo.CODE;
                                            eventInfo.EventAk = eventApiInfo.AK;
                                            eventInfo.UpdateDate = DateTime.Now;
                                            eventInfo.UpdateUser = CurrentUserId;
                                            updateEventList.Add(eventInfo);
                                        }
                                    }
                                }
                            }
                            _context.FrIpEventTimeSlots.RemoveRange(delEventTimeSlots);
                            await _context.FrIpEventTimeSlots.AddRangeAsync(insertEventTimeSlots);
                            await _context.FrIpEvents.AddRangeAsync(insertEventList);
                            await _context.FrIpProducts.AddRangeAsync(insertProductList);
                            await _context.FrIpProductEvents.AddRangeAsync(insertProductEventList);

                            _context.FrIpProducts.UpdateRange(updateProductList);
                            _context.FrIpEvents.UpdateRange(updateEventList);

                            await _context.SaveChangesAsync();
                        }
                    }
                }
                return resultMsg.SetResultMsg(
                 (int)ResultCode.Success,
                 HelperUtility.GetDescription(ResultCode.Success),
                 null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
                return resultMsg.SetResultMsg(
                 (int)ResultCode.ErrorOnRequestUnMarshalling,
                 HelperUtility.GetDescription(ResultCode.ErrorOnRequestUnMarshalling),
                 null);
            }
        }

        [HttpPost("CheckOutProducts")]
        public async Task<ActionResult<ResultMsg>> CheckOutProducts([FromBody] CheckOutProductsRequest requestModel)
        {
            var resultMsg = new ResultMsg();
            try
            {
                if (string.IsNullOrWhiteSpace(requestModel.ProductList))
                {
                    return resultMsg.SetResultMsg(
                     (int)ResultCode.NoDataFound,
                     HelperUtility.GetDescription(ResultCode.FieldRequired),
                     "ProductList is none");
                }

                List<CheckOutProductsRequest_ProductInfo> list = JsonConvert.DeserializeObject<List<CheckOutProductsRequest_ProductInfo>>(requestModel.ProductList);
                List<CheckOutProductsResponse> rList = new List<CheckOutProductsResponse>();
                List<ProductEventReqeust> productEventList = new List<ProductEventReqeust>();
                foreach (var item in list)
                {
                    var p = await _context.FrIpProducts.FindAsync(new Guid(item.ProductId));
                    if (p == null)
                    {
                        rList.Add(new CheckOutProductsResponse()
                        {
                            Type = 2,
                            ProductId = item.ProductId,
                            ProductName = item.ProductName,
                        });
                    }
                    else
                    {
                        productEventList.Add(new ProductEventReqeust()
                        {
                            MatrixCellAK = p.MatrixCellAk,
                            IsRequired = p.IsRequired.GetValueOrDefault(),
                            Qty = item.ProductNum.ToString(),
                        });
                    }
                }

                if (productEventList != null && productEventList.Count > 0)
                {
                    CheekOutRequest request = new CheekOutRequest();
                    request.productEventList = productEventList;
                    var results = await CheckOut(request);
                    if (results != null && results.Count > 0)
                    {
                        foreach (var item in results) {
                            var reqPro = productEventList.Where(x=>x.MatrixCellAK == item.AK).FirstOrDefault();
                            if (reqPro != null)
                            {
                                if (Convert.ToInt32(item.QTY) < Convert.ToInt32(reqPro.Qty))
                                {
                                    var p = _context.FrIpProducts.Where(x => x.MatrixCellAk == item.AK).FirstOrDefault();
                                    if (p != null) {
                                        var _p = list.Where(x => x.ProductId.ToLower() == p.Id.ToString().ToLower()).FirstOrDefault();
                                        if (_p != null)
                                        {
                                            rList.Add(new CheckOutProductsResponse()
                                            {
                                                Type = 1,
                                                ProductId = _p.ProductId,
                                                ProductName = _p.ProductName,
                                                CurrentNum = Convert.ToInt32(item.QTY),
                                            });
                                        }
                                    }
                                }
                            }                            
                        }
                    }                    
                }

                return resultMsg.SetResultMsg(
                (int)ResultCode.Success,
                HelperUtility.GetDescription(ResultCode.Success),
                rList);
            }
            catch (Exception ex)
            {
                _logger.LogError("Common/CheckOutProducts Error:" + ex.Message);
                return resultMsg.SetResultMsg(
                 (int)ResultCode.ErrorOnRequestUnMarshalling,
                 HelperUtility.GetDescription(ResultCode.ErrorOnRequestUnMarshalling),
                 ex.Message);
            }
        }

        [NonAction]
        public async Task<List<ITEM1>> CheckOut(CheekOutRequest request)
        {
            var resultMsg = new ResultMsg();

            var item1List = new List<ITEM1>();

            var requestItemList = new List<ITEM>();

            var trueList = request.productEventList.Where(x => x.IsRequired).ToList();
            var falseList = request.productEventList.Where(x => !x.IsRequired).ToList();

            if (trueList != null && trueList.Count > 0)
            {
                foreach (var item in trueList)
                {
                    requestItemList.Add(new ITEM()
                    {
                        AK = item.MatrixCellAK.ToString(),
                        QTY = item.Qty
                    });
                }
                var loginResp = await Login();

                var client = new WsAPIOrderSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:OrderApiUrl"]));
                using (var operationContextScope = new OperationContextScope(client.InnerChannel))
                {
                    // 添加HTTP请求头  
                    var httpRequestProperty = new HttpRequestMessageProperty();
                    httpRequestProperty.Headers["token"] = loginResp.Toekn;
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                    // 调用WebService方法  
                    var result = await client.CheckOutAsync(new SHOPCART()
                    {
                        FLAG = new FLAG()
                        {
                            APPROVED = "true",
                            PAID = "true",
                            ENCODED = "true",
                            VALIDATED = "true",
                            COMPLETED = "true",
                        },
                        RESERVATION = new RESERVATION()
                        {
                            RESERVATIONOWNER = new RESERVATIONOWNER()
                            {
                                AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK
                            },
                            BILLINGACCOUNT = new BILLINGACCOUNT()
                            {
                                AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK
                            },
                            LOGGEDACCOUNT = new LOGGEDACCOUNT() { AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK }
                        },
                        LANGUAGEAK = "en-GB",
                        ITEMLIST = requestItemList.ToArray()
                    });


                    //var oldProdcut = new List<FrIpProduct>();

                    if (result.@return != null && result.@return != null && result.@return.ERROR != null && result.@return.ERROR.CODE == "200")
                    {
                        item1List.AddRange(result.@return.ITEMLIST.ToList());
                    }
                }
            }

            if (falseList != null && falseList.Count > 0)
            {
                foreach (var item in falseList)
                {
                    requestItemList.Add(new ITEM()
                    {
                        AK = item.MatrixCellAK.ToString(),
                        QTY = item.Qty
                    });
                }
                var loginResp = await Login();

                var client = new WsAPIOrderSoapClient(new BasicHttpsBinding() { MaxReceivedMessageSize = 2147483647 }, new EndpointAddress(Configuration["AsmxUrl:OrderApiUrl"]));
                using (var operationContextScope = new OperationContextScope(client.InnerChannel))
                {
                    // 添加HTTP请求头  
                    var httpRequestProperty = new HttpRequestMessageProperty();
                    httpRequestProperty.Headers["token"] = loginResp.Toekn;
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

                    // 调用WebService方法  
                    var result = await client.CheckOutAsync(new SHOPCART()
                    {
                        FLAG = new FLAG()
                        {
                            APPROVED = "true",
                            PAID = "true",
                            ENCODED = "true",
                            VALIDATED = "true",
                            COMPLETED = "true",
                        },
                        RESERVATION = new RESERVATION()
                        {
                            RESERVATIONOWNER = new RESERVATIONOWNER()
                            {
                                AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK
                            },
                            BILLINGACCOUNT = new BILLINGACCOUNT()
                            {
                                AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK
                            },
                            LOGGEDACCOUNT = new LOGGEDACCOUNT() { AK = loginResp.B2BAccountLogin.ACCOUNT.BASICINFO.ACCOUNTAK }
                        },
                        LANGUAGEAK = "en-GB",
                        ITEMLIST = requestItemList.ToArray()
                    });


                    //var oldProdcut = new List<FrIpProduct>();

                    if (result.@return != null && result.@return != null && result.@return.ERROR != null && result.@return.ERROR.CODE == "200")
                    {
                        item1List.AddRange(result.@return.ITEMLIST.ToList());
                    }
                }
            }

            return item1List;
        }

        [HttpPost("GetEventDetails")]
        public async Task GetEventDetails(GetEventDetailRequest request)
        {
            try
            {
                var requestUrl = Configuration["TicketRequestUrl"];
                string requestHost = Configuration["TicketRequestHost"]; 
                var dic = new Dictionary<string, object>();
                string meothName = "GetEventDetails";   //服务的方法名
                var httpClientHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true
                };

                StringBuilder contentString = new StringBuilder();

                foreach (var item in request.EventAkList)
                {
                    contentString.Append($"<string>{item}</string>");
                }
                string contentValue = contentString.ToString();
                string content = $@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                   <soap:Body>
                     <{meothName} xmlns=""{requestHost}"">
                    <EventAKList>
                         {contentValue}
                </EventAKList>
                     </{meothName}>
                 </soap:Body>
              </soap:Envelope>";
                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "text/xml");

                HttpClient client = new HttpClient(httpClientHandler);

                var response = await client.PostAsync(requestUrl, httpContent);
            }
            catch (Exception ex)
            {

            }
        }

        [NonAction]
        public async Task<LoginResponse> Login()
        {
            var response = new LoginResponse();
            try
            {
                var AUsername = Configuration["AUsername"];
                var APsw = Configuration["APsw"];

                var request = new B2BAccountLogInRequest()
                {
                    AUsername = AUsername,
                    APsw = APsw
                };
                var result = await _apiAccountService.B2BAccountLogInAsync(request);
                string token = await GetToken();
                if (string.IsNullOrWhiteSpace(token))
                {
                    return null;
                }

                response.Toekn = token;
                response.B2BAccountLogin = result.@return;
                return response;
            }
            catch (Exception ex)
            {
                return response;
            }
        }

        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="doc"></param>
        /// <param name="dbData"></param>
        /// <returns></returns>
        [NonAction]
        public T Deserialize<T>(XDocument doc, string dbData) where T : class
        {
            var data = doc.Descendants(dbData).First();
            var serializer = new XmlSerializer(typeof(T));
            var result = serializer.Deserialize(data.CreateReader()) as T;
            return result;
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        [NonAction]
        public string Serialize<T>(T t) where T : class
        {
            var serializer = new XmlSerializer(typeof(T));
            var str = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(str);
            serializer.Serialize(writer, t);
            return str.ToString();
        }

    }
}
